package com.xbongbong.pro.statistics.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.statistic.service.WorkbenchService;
import com.xbongbong.pro.statistic.workbench.pojo.dto.CommunicatePlanCountDTO;
import com.xbongbong.pro.statistic.workbench.pojo.dto.DataCockpitDTO;
import com.xbongbong.pro.statistic.workbench.vo.CommunicatePlanCountVO;
import com.xbongbong.pro.statistic.workbench.vo.DataCockpitVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Map;
import java.util.Objects;

/**
 * 工作台
 * 创建时间 2021/2/4 3:10 PM
 * 修改时间 2021/2/4 3:10 PM
 * @author chy
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/chart/workbench")
public class WorkbenchController {
    private static final Logger LOG = LoggerFactory.getLogger(WorkbenchController.class);
    @Resource
    private WorkbenchService workbenchService;
    @Resource
    private Environment env;

    /**
     * 数据驾驶舱
     * @param params
     * @return
     * 创建时间 2021/2/19 7:10 PM
     * 修改时间 2021/2/19 7:10 PM
     * @author chy
     */
    @PostMapping(value = "/dataCockpit")
    public String dataCockpit(@RequestHeader Map<String, String> headers, @RequestParam Map<String, Object> params) {
        LOG.info("dataCockpit params:" + params);
        XbbResponse<DataCockpitVO> response;
        try {
            checkSignature(headers);
        } catch (XbbException e) {
            response = new XbbResponse<>(e);
            return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
        }
        String corpid = (String)params.get("corpId");
        String userId = (String)params.get("userid");
        DataCockpitDTO dataCockpitDto = new DataCockpitDTO();
        dataCockpitDto.setCorpid(corpid);
        dataCockpitDto.setUserId(userId);
        try {
            DataCockpitVO dataCockpitVO = workbenchService.dataCockpit(dataCockpitDto);
            response = new XbbResponse<>(dataCockpitVO);
        } catch (XbbException e) {
            e.printStackTrace();
            response = new XbbResponse<>(e);
        }
        String ret = JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
        LOG.info("dataCockpit ret:" + ret);
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 访客计划数
     * @param headers
     * @param params
     * @return
     * 创建时间 2021/2/19 7:10 PM
     * 修改时间 2021/2/19 7:10 PM
     * @author chy
     */
    @PostMapping(value = "/communicatePlanCount")
    public String communicatePlanCount(@RequestHeader Map<String, String> headers, @RequestParam Map<String, Object> params) {
        LOG.info("communicatePlanCount params:" + params);
        XbbResponse<CommunicatePlanCountVO> response;
        try {
            checkSignature(headers);
        } catch (XbbException e) {
            response = new XbbResponse<>(e);
            return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
        }
        String corpid = (String)params.get("corpId");
        String userId = (String)params.get("userid");
        CommunicatePlanCountDTO communicatePlanCountDTO = new CommunicatePlanCountDTO();
        communicatePlanCountDTO.setCorpid(corpid);
        communicatePlanCountDTO.setUserId(userId);
        try {
            CommunicatePlanCountVO communicatePlanCountVO = workbenchService.communicatePlanCount(communicatePlanCountDTO);
            response = new XbbResponse<>(communicatePlanCountVO);
        } catch (XbbException e) {
            response = new XbbResponse<>(e);
        }
        String ret = JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
        LOG.info("communicatePlanCount ret:" + ret);
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    private boolean checkSignature(Map<String, String> headers) throws XbbException {
        String apiSecret = env.getProperty("com.xbongbong.workbench.apiSecret");
        String timestampStr = headers.get("x-ddpaas-signature-timestamp");
        Long timestamp;
        try {
            timestamp = Long.parseLong(timestampStr);
        } catch (Exception e) {
            LOG.error("Long.parseLong error");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, "参数不合法");
        }
        String signature = headers.get("x-ddpaas-signature");
        if (Objects.equals(signature, calcSignature(apiSecret, timestamp))) {
            return true;
        }
        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, "参数不合法");
    }

    private String calcSignature(String apiSecret, long ts) throws XbbException {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec key = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA256");
            mac.init(key);
            return Base64.getEncoder().encodeToString(mac.doFinal(Long.toString(ts).getBytes()));
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002.getCode(), "参数不合法");
        }
    }
}
